
// Definition for a binary tree node.
function TreeNode(val, left, right) {
    this.val = (val===undefined ? 0 : val)
    this.left = (left===undefined ? null : left)
    this.right = (right===undefined ? null : right)
}
function createTree(arr) {
  let nodeArr = [];
  for(let i = 0; i < arr.length; i++) {
    let node;
    if(!arr[i]) {
      node = null;
    } else {
      node = new TreeNode(arr[i]);
    }
    nodeArr.push(node);
  }
  for(let i = 0; i < nodeArr.length; i++) {
    if(2 * i + 1 < nodeArr.length) {
      nodeArr[i].left = nodeArr[2 * i + 1];
    }
    if(2 * i + 2 < nodeArr.length) {
      nodeArr[i].right = nodeArr[2 * i + 2];
    }
  }
  return nodeArr[0];
}
/**
 * @param {TreeNode} root
 * @return {string}
 */
var tree2str = function(root) {
  if(!root) return "";
  if(!root.left && !root.right) return (root.val).toString();
  function preView(node){
    if(!node){
      return "()";
    }
    return `${node.val}(${preView(node.left)})(${preView(node.right)})`;
  }
  let result = preView(root), final = "";
  function replaceBrackets(str) {
    const reg = /(\(\))([^\(\d+])/g;
    if(reg.test(str)) {
      str = str.replace(reg, function(...payload) {
        return payload[0][payload[0].length - 1];
      });
      const reg1 = /\(\)$/g
      if(reg1.test(str)) {
        str = str.replace(reg1, function() {
          return "";
        })
      }
      return replaceBrackets(str);
    } else {
      return str;
    }
  }
  result = replaceBrackets(result);
  return result;
};
let root = [1,2,3,4];
console.log(tree2str(createTree(root)));
root = [1,2,3,null,4];
console.log(tree2str(createTree(root)));
root = [1,2,null,3,4];
console.log(tree2str(createTree(root)));
